#include <iostream>
#include <string>
#include <memory>
#include <unistd.h>
#include "TcpServer.hpp"
#include "Calculator.hpp"
#include "Protocol.hpp"
#include "Factory.hpp"
using namespace std;

// string ServerHandler(string& message, Protocol pro)
// {
//     unique_ptr<Factory> ft(new Factory());
//     while (true)
//     {
//         // 1. 接收有效载荷
//         char resquest[1024];
//         ssize_t n = recv(sock->GetSockFd(), resquest, sizeof(resquest), 0);
//         resquest[n] = 0;
//         // 2. 有效载荷反序列化
//         shared_ptr<Calculator::Request> req = ft->BuildCalRequest();
//         req->Deserialize(resquest);
//         // 3. 处理数据，并构建响应
//         shared_ptr<Calculator::Response> rep = req->Result();
//         // 4. 响应序列化
//         string response;
//         rep->Serialize(response);
//         // 5. 发送响应序列化
//         send(sock->GetSockFd(), response.c_str(), response.size(), 0);
//         sleep(1);
//     }
// }

string ServerHandler(string &message, bool *ok, Protocol pro)
{
    *ok = true;
    unique_ptr<Factory> ft(new Factory());
    while (true)
    {
        // 1. 报文解包
        string content;
        if (!pro.Unpackage(message, &content))
        {
            return "";
        }
        // 2. 有效载荷反序列化
        shared_ptr<Calculator::Request> req = ft->BuildCalRequest();
        if (!req->Deserialize(content))
        {
            *ok = false;
            return "";
        }
        // 3. 处理数据，并构建响应
        shared_ptr<Calculator::Response> rep = req->Result();
        // 4. 响应序列化
        string response;
        if (!rep->Serialize(response))
        {
            *ok = false;
            return "";
        }
        // 5. 响应封装成报文
        string message;
        pro.Package(response, &message);
        return message;
    }
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        cout << "Incorrect use, correct use:\n"
             << "    " << argv[0] << " port" << endl;
    }
    uint16_t localport = stoi(argv[1]);
    unique_ptr<TcpServer> up(new TcpServer(localport, bind(&ServerHandler, placeholders::_1, placeholders::_2, Protocol())));

    up->Loop();

    return 0;
}